﻿using System;
using System.Net;
using System.IO;
using System.Xml;

namespace LiveNet.Silverlight
{
    public sealed partial class LiveMedia
    {
        private delegate void ResponseCompletedDelegate(Stream stream);
        private delegate void PutResponseCompletedDelegate();
        private delegate void GetNodeResult(XmlNode xmlnode);

        private void MakeGetRequest(Uri url, ResponseCompletedDelegate response)
        {
            HttpWebRequest request = BuildRequest(url, "GET");

            try
            {
                using (HttpWebResponse httpresponse = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream stream = httpresponse.GetResponseStream())
                    {
                        response(stream);
                    }
                }
            }
            catch (WebException ex)
            {
                throw new LiveNetRequestException(ex.Message, ex);
            }
        }

        private bool MakeDeleteRequest(Uri url, bool add)
        {
            HttpWebRequest request = BuildRequest(url, "DELETE");
            
            try
            {
                using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
                {
                    return true;                    
                }
            }
            catch (WebException ex)
            {
                if (add && ex.Message.Equals("The remote server returned an error: (404) Not Found."))
                {
                    return true;
                }
                else
                {
                    throw new LiveNetRequestException(ex.Message, ex);
                }
            }
        }

        private void MakePutRequest(Uri url, Stream stream, PutResponseCompletedDelegate responseCompleted)
        {
            HttpWebRequest request = BuildRequest(url, "PUT");
            request.ContentType = "application/zip";

            using (Stream requestStream = request.GetRequestStream())
            {
                CopyStream(stream, requestStream);
            }

            try
            {
                using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
                {
                    responseCompleted();
                }
            }
            catch (WebException ex)
            {
                throw new LiveNetRequestException(ex.Message, ex);
            }

        }

        private static void ParseGetRequest(Stream getstream, string name, GetNodeResult result)
        {
            using (Stream stream = getstream)
            {
                XmlDocument xmld = new XmlDocument();
                string xpath = "/fileSets/fileSet";

                if (!string.IsNullOrEmpty(name))
                {
                    xpath += "[@name=\"" + name + "\"]";
                }

                using (StreamReader reader = new StreamReader(stream))
                {
                    xmld.LoadXml(reader.ReadToEnd());
                }

                XmlNodeList xmlnl = xmld.SelectNodes(xpath);

                foreach (XmlNode xmlnode in xmlnl)
                {
                    result(xmlnode);
                }
            }
        }

        private static void ParseGetFiles(Stream getstream, GetNodeResult result)
        {
            using (Stream stream = getstream)
            {
                XmlDocument xmld = new XmlDocument();
                
                using (StreamReader reader = new StreamReader(stream))
                {
                    xmld.LoadXml(reader.ReadToEnd());
                }

                XmlNodeList xmlnl = xmld.SelectNodes("/fileSets/file");

                foreach (XmlNode xmlnode in xmlnl)
                {
                    result(xmlnode);
                }
            }
        }

        private MediaFileSet ParseFileSet(XmlNode xmlnode)
        {
            string name = xmlnode.Attributes["name"].Value;
            bool isApplication = Convert.ToBoolean(xmlnode.Attributes["isApp"].Value);
            
            return new MediaFileSet(this, AccountId, name, isApplication);                        
        }

        private static MediaFile ParseFiles(XmlNode xmlnode, MediaFileSet fileset)
        {
            string filename = xmlnode.Attributes["name"].Value;
            string mimetype = xmlnode.Attributes["mimeType"].Value;
            int bytesize = Convert.ToInt32(xmlnode.Attributes["size"].Value);
            
            return new MediaFile(filename, mimetype, bytesize, fileset);
        }
    }
}